import { Component, EventEmitter, OnInit, Output, ViewChild } from "@angular/core";
import { NzMessageService } from "ng-zorro-antd/message";
import { RoleService } from "../role.service";
import { FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms";
import { SysMenuService } from "../../menu-list/sys-menu.service";
import { NzTreeComponent, NzTreeNode, NzTreeNodeOptions } from "ng-zorro-antd/tree";
import { NzTransferComponent, TransferChange, TransferItem, TransferSelectChange } from "ng-zorro-antd/transfer";
import { AccessItemService } from "../../../sys/api-access/access-item/access-item.service";

@Component({
  selector: "role-list-edit",
  templateUrl: "./role-edit.component.html"
})
export class RoleEditComponent implements OnInit {


  constructor(private formBuilder: FormBuilder,
              private menuService: SysMenuService,
              private msgSrv: NzMessageService,
              private roleSrv: RoleService,
              private accessItemService: AccessItemService
  ) {
  }

  @Output() voted = new EventEmitter();

  validateForm!: FormGroup;

  // 菜单数据
  menus = [];
  // 接口数据
  apiData : TransferItem [] = [];

  tempApiDate = [];

  visible = false;
  value?: [];

  isUpdate = false;

  defaultSelectedKeys = [];
  @ViewChild("nzTree") nzTree: NzTreeComponent;

  @ViewChild("nzTransferComponent") nzTransferComponent: NzTransferComponent;

  open(): void {
    this.visible = true;
    this.isUpdate = false;
  }

  edit(param) {
    this.visible = true;
    this.value = param?.parent?.id;
    this.isUpdate = true;

    if (param) {
      this.validateForm.patchValue(param);
      this.defaultSelectedKeys = param.menuIds;
      this.apiData = [];
      this.changeToRight(param.accessMethodIds);
      this.nzTransferComponent.moveToLeft();
    } else {
      this.validateForm.reset();
    }
  }

  close(): void {
    this.visible = false;
  }

  submitForm(): void {
    for (const i in this.validateForm.controls) {
      this.validateForm.controls[i].markAsDirty();
      this.validateForm.controls[i].updateValueAndValidity();
    }

    let checkedNodeList = this.nzTree.getCheckedNodeList();

    let keys = checkedNodeList.map((item, index, array) => {
      return item.key;
    });

    // 获取接口数据
    const rightApi = this.apiData.filter(item => item.direction === "right").map(item => item.id);

    this.validateForm.patchValue({ "menuIds": keys });
    this.validateForm.patchValue({ "accessMethodIds": rightApi });

    this.roleSrv.update(this.validateForm.value).subscribe((res) => {
      if (res.code === 1) {
        this.msgSrv.success("保存完成");
        this.close();
        this.voted.emit();
      } else {
        this.msgSrv.error(res.message);
      }
    });
  }

  updateConfirmValidator(): void {
    /** wait for refresh value */
    Promise.resolve().then(() => this.validateForm.controls.checkPassword.updateValueAndValidity());
  }

  confirmationValidator = (control: FormControl): { [s: string]: boolean } => {
    if (!control.value) {
      return { required: true };
    } else if (control.value !== this.validateForm.controls.password.value) {
      return { confirm: true, error: true };
    }
    return {};
  };

  getCaptcha(e: MouseEvent): void {
    e.preventDefault();
  }


  ngOnInit(): void {
    this.validateForm = this.formBuilder.group({
      id: [null],
      roleCode: [null, [Validators.required]],
      roleName: [null, [Validators.required]],
      status: [null, [Validators.required]],
      menuIds: [null],
      accessMethodIds: [null],
      memo: [null]
    });

    // 加载所有菜单
    this.menuService.menuTree().subscribe((res) => {
      if (res.code === 1) {
        this.menus = res.data;
      } else {
        this.msgSrv.error(res.message);
      }
    });
    // 加载所有权限接口
    this.accessItemService.findAll().subscribe(res => {
      if (res.code === 1) {
        this.tempApiDate = res.data;
      } else {
        this.msgSrv.error(res.message);
      }
    });
  }

  nzDisplayWith(node: NzTreeNode) {
    return node.title;
  }

  onChange($event: string): void {
    console.log($event);
  }

  checkedNodeList: NzTreeNode[] = [];


  checkBoxChange(node: NzTreeNode, onItemSelect: (item: NzTreeNodeOptions) => void): void {
    if (node.isDisabled) {
      return;
    }
    node.isChecked = !node.isChecked;
    if (node.isChecked) {
      this.checkedNodeList.push(node);
    } else {
      const idx = this.checkedNodeList.indexOf(node);
      if (idx !== -1) {
        this.checkedNodeList.splice(idx, 1);
      }
    }
  }

  select(ret: TransferSelectChange): void {
    console.log('nzSelectChange', ret);
  }

  change(ret: TransferChange): void {
    console.log('nzChange', ret);
    const listKeys = ret.list.map(l => l.key);
    const hasOwnKey = (e: TransferItem) => e.hasOwnProperty('key');
    this.apiData = this.apiData.map(e => {
      if (listKeys.includes(e.key) && hasOwnKey(e)) {
        if (ret.to === 'left') {
          delete e.hide;
        } else if (ret.to === 'right') {
          e.hide = false;
        }
      }
      return e;
    });
  }

  // 选中ID的移动值右边
  private changeToRight(accessMethodIds) {

    this.tempApiDate.forEach(item => {
        item.direction = "left";
    });

    accessMethodIds.forEach(id => {
      this.tempApiDate.forEach(item => {
        if (item.id === id) {
          item.direction = "right";
        }
      });
    });

    this.apiData = this.tempApiDate;

  }
}
